<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>vue32022 | 学习笔记</title><meta name="author" content="lzoxun"><meta name="copyright" content="lzoxun"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Options Api (选项API)开启 vue1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192">
<meta property="og:type" content="article">
<meta property="og:title" content="vue32022">
<meta property="og:url" content="http://example.com/2023/07/22/web/vue/vue-vue3-coderw/index.html">
<meta property="og:site_name" content="学习笔记">
<meta property="og:description" content="Options Api (选项API)开启 vue1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png">
<meta property="article:published_time" content="2023-07-22T07:14:09.697Z">
<meta property="article:modified_time" content="2023-07-22T07:14:09.697Z">
<meta property="article:author" content="lzoxun">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/2023/07/22/web/vue/vue-vue3-coderw/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":true,"top_n_per_article":1,"unescape":true,"languages":{"hits_empty":"找不到您查询的内容：${query}","hits_stats":"共找到 ${hits} 篇文章"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"bottom-left"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'vue32022',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-07-22 15:14:09'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          const now = new Date()
          const hour = now.getHours()
          const isNight = hour <= 6 || hour >= 18
          if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
          else if (t === 'light') activateLightMode()
          else activateDarkMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
  const $loadingBox = document.getElementById('loading-box')
  const $body = document.body
  const preloader = {
    endLoading: () => {
      $body.style.overflow = ''
      $loadingBox.classList.add('loaded')
    },
    initLoading: () => {
      $body.style.overflow = 'hidden'
      $loadingBox.classList.remove('loaded')
    }
  }

  preloader.initLoading()
  window.addEventListener('load',() => { preloader.endLoading() })

  if (false) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
  }
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">108</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">1</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header"><nav id="nav"><span id="blog-info"><a href="/" title="学习笔记"><span class="site-name">学习笔记</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">vue32022</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-07-22T07:14:09.697Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-07-22T07:14:09.697Z" title="更新于 2023-07-22 15:14:09">2023-07-22</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="vue32022"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="Options-Api-选项API"><a href="#Options-Api-选项API" class="headerlink" title="Options Api (选项API)"></a>Options Api (选项API)</h2><h4 id="开启-vue"><a href="#开启-vue" class="headerlink" title="开启 vue"></a>开启 vue</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、引入</span></span><br><span class="line">&lt;script src=<span class="string">&#x27;https://unpkg.com/vue@next&#x27;</span>&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、创建模板内容 2.0的 options Api</span></span><br><span class="line"><span class="keyword">const</span> app = <span class="title class_">Vue</span>.<span class="title function_">createApp</span>(&#123;</span><br><span class="line">    <span class="attr">template</span>: <span class="string">`&lt;h2&gt;hello &#123;&#123;msg&#125;&#125;!&lt;/h2`</span>, <span class="comment">// template的内容会覆盖app里的html，如果没写 temp vue将挂载节点里的html作为熏染模板，</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 劫持返回的对象数据，通过 Object.defineProperty 或 new Proxy 添加到vue的响应式系统</span></span><br><span class="line">    <span class="attr">data</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123; <span class="comment">// 3.0 所有场景必须是函数 </span></span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            <span class="attr">msg</span>: <span class="string">&quot;word&quot;</span>,</span><br><span class="line">            <span class="attr">info</span>: <span class="string">&quot;this a info&quot;</span>,</span><br><span class="line">            <span class="attr">coutn</span>: <span class="number">2</span>,</span><br><span class="line">            <span class="attr">imgurl</span>: <span class="string">&quot;http://xxx/xxx/xxx.jpg&quot;</span>,</span><br><span class="line">            <span class="attr">infos</span>:&#123;<span class="attr">a</span>:<span class="number">1</span>,<span class="attr">b</span>:<span class="number">2</span>&#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;，</span><br><span class="line">    <span class="comment">// filters 部分代码 vue3已经删除，功能通过 methods 或 computed 的可以实现</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 不可以用箭头函数(箭头无作用域，里面的this无法指向vue对象)</span></span><br><span class="line">    <span class="attr">methods</span>: &#123;</span><br><span class="line">        <span class="title function_">connect_met</span>(<span class="params"></span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">info</span> +“ ”+ <span class="variable language_">this</span>.<span class="property">msg</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="title function_">getData</span>(<span class="params"></span>)&#123;&#125; </span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 计算属性, （包含响应式数据的计算），涉及到的属性变化，结果跟着变化</span></span><br><span class="line"><span class="comment">     * connect 会被混入到实例中, 可以通过 this.connetc 使用</span></span><br><span class="line"><span class="comment">     * 和 methods差别 存在缓存</span></span><br><span class="line"><span class="comment">     *     模板中 &#123;&#123; connect_met() &#125;&#125; 使用三次,执行了三次</span></span><br><span class="line"><span class="comment">     *     模板中 &#123;&#123; connect &#125;&#125; 使用三次，只会计算一次</span></span><br><span class="line"><span class="comment">     *     this.info 和 this.msg 发生变化，自动更新 connect</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="attr">computed</span>:&#123;</span><br><span class="line">        <span class="title function_">connect</span>(<span class="params"></span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">info</span> +<span class="string">&quot; &quot;</span>+ <span class="variable language_">this</span>.<span class="property">msg</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">connect2</span>:&#123;</span><br><span class="line">            <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">info</span> +<span class="string">&quot; &quot;</span>+ <span class="variable language_">this</span>.<span class="property">msg</span></span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params">value</span>)&#123;</span><br><span class="line">                <span class="comment">// 一些列操作</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">        </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 注册局部组件</span></span><br><span class="line"><span class="comment">     * 导入的时候尽量大驼峰取名，组件名与组件是一样的就可以缩写了</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="attr">components</span>:&#123;</span><br><span class="line">        <span class="string">&quot;ProductItem&quot;</span>:<span class="title class_">ProductItem</span>,</span><br><span class="line">         <span class="title class_">ProductItem</span></span><br><span class="line">    &#125;,</span><br><span class="line">        </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 监听属性变化，某个属性变化，去做一件事情</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="attr">watch</span>:&#123;</span><br><span class="line">        <span class="title function_">info</span>(<span class="params">n,o</span>)&#123;</span><br><span class="line">            </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="title function_">infos</span>(<span class="params">n,o</span>)&#123;</span><br><span class="line">            <span class="comment">// 整个infos发生变化，得到的n是一个 Proxy对象</span></span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Vue</span>.<span class="title function_">toRaw</span>(n)) <span class="comment">// 获取原生对象</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">infos</span>:&#123;</span><br><span class="line">            <span class="title function_">handler</span>(<span class="params">n,o</span>)&#123;</span><br><span class="line">                <span class="comment">// 侦听对象某个属性变化，默认无法深度监听</span></span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Vue</span>.<span class="title function_">toRaw</span>(n)) <span class="comment">// 获取原生对象</span></span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="attr">deep</span>:<span class="literal">true</span>,</span><br><span class="line">            <span class="attr">immediate</span>:<span class="literal">true</span>  <span class="comment">// 第一次立即执行</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="string">&quot;infos.a&quot;</span>:(n,o)&#123;</span><br><span class="line">            <span class="comment">// 直接侦听对象属性</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 *   生命周期</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">     <span class="title function_">created</span>(<span class="params"></span>)&#123;</span><br><span class="line">         <span class="variable language_">this</span>.$watch(<span class="string">&quot;msg&quot;</span>,<span class="function">(<span class="params">n,o</span>)=&gt;</span>&#123;&#125;,&#123;<span class="attr">deep</span>:<span class="literal">true</span>&#125;) <span class="comment">// 逻辑中监听</span></span><br><span class="line">     &#125; </span><br><span class="line">     </span><br><span class="line">    </span><br><span class="line"> </span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、挂载到页面已存在的节点</span></span><br><span class="line">app.<span class="title function_">mount</span>(<span class="string">&quot;#app&quot;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h4 id="模板语法"><a href="#模板语法" class="headerlink" title="模板语法"></a>模板语法</h4><blockquote>
<p>template 中的语法  (react 通过jsx 编写)</p>
</blockquote>
<p>mustache 语法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * &#123;&#123;&#125;&#125;</span></span><br><span class="line"><span class="comment"> * &#123;&#123;msg&#125;&#125;  普通数据绑定</span></span><br><span class="line"><span class="comment"> * &#123;&#123;count*2&#125;&#125; &#123;&#123;info.split(&quot; &quot;)&#125;&#125; &#123;&#123;a&gt;2?&quot;0&quot;:&quot;1&quot;&#125;&#125; 表达式,对 data 的数据进行加工再渲染</span></span><br><span class="line"><span class="comment"> * &#123;&#123;count*2&#125;&#125; &#123;&#123;info.split(&quot; &quot;)&#125;&#125; &#123;&#123;a&gt;2?&quot;0&quot;:&quot;1&quot;&#125;&#125; 表达式,对 data 的数据进行加工再渲染</span></span><br><span class="line"><span class="comment"> * &#123;&#123; getData(msg) &#125;&#125; 调用methods 的方法，传入data的参数</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<p>基本指令</p>
<blockquote>
<p>  标签中使用 </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * v-ones   只渲染一次，数据变化指令标签内部所有data不更新</span></span><br><span class="line"><span class="comment"> * v-text 与 v-html 是否将带html标签的数据效果呈现</span></span><br><span class="line"><span class="comment"> * v-pre  标签里所有东西当做字符串 包括 &#123;&#123;&#125;&#125;</span></span><br><span class="line"><span class="comment"> * v-cloak 防止js未加载出来时，页面出现&#123;&#123;msg&#125;&#125; 的问题 （配合 style [v-cloak]&#123;display:none&#125; 才行） </span></span><br><span class="line"><span class="comment"> * v-memo=[name,msg] 3.2+  v-memo指令作用的标签内部(子树)数据不实时更新，只有name 或 msg数据变化了，再一起更新</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<p>v-bang、绑定class和style</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * v-bind  缩写 : 动态绑定属性的值</span></span><br><span class="line"><span class="comment"> * v-bind:src=&quot;imgurl&quot;  或  :src=&quot;imgurl&quot;  </span></span><br><span class="line"><span class="comment"> * :class=&#123;active:bool&#125; 或  :class=&quot;getClassList()&quot;    函数中 retrun &#123;active:true,msg:false&#125;</span></span><br><span class="line"><span class="comment"> * :style=&#123;&quot;font-size&quot;:size + &quot;px&quot;&#125;  驼峰或引号都行</span></span><br><span class="line"><span class="comment"> * :[namexxx]=&quot;123&quot; // 动态绑定属性名</span></span><br><span class="line"><span class="comment"> * v-bind=&quot;infos&quot; // 绑定一个对象 infos:&#123;a:1,b:2&#125; 直接绑定a和b连个属性</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<p>绑定事件</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * v-on 缩写 @</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@click</span>=&quot;getData&quot; // 事件发生时做一件事情，直接做，或通过函数做</span></span><br><span class="line"><span class="comment"> * v-on=&#123;click:getData,mousemove:getData2&#125; 批量绑定</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@click</span>=&quot;getData&quot; // 没参数 event 参数默认存在</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@click</span>=&quot;getData($event,msg)&quot; // 有参数，需要手动传入事件对象</span></span><br><span class="line"><span class="comment"> * 事件修饰符</span></span><br><span class="line"><span class="comment"> *     <span class="doctag">@click</span>.stop=&quot;xxx&quot; 阻止事件冒泡 (原生通过 event.stopPropagation() 阻止)	</span></span><br><span class="line"><span class="comment"> *	         .prevent    阻止默认行为	(原生通过 event.preventDefault() 阻止)	</span></span><br><span class="line"><span class="comment"> *           .capture    使用捕获模式</span></span><br><span class="line"><span class="comment"> *           .self       事件绑定原生自己触发事件才生效</span></span><br><span class="line"><span class="comment"> *           .ones       只触发一次</span></span><br><span class="line"><span class="comment"> *           .left/right/middle 点击左/右/中按键时才触发</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<p>v-model</p>
<blockquote>
<p>  表单设置双向数据绑定 ，如果手动实现，@input 的时候执行函数，手动让 其他数据变化</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">v-model</span>=<span class="string">&quot;selectText&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">:value</span>=<span class="string">&quot;searchText&quot;</span> @<span class="attr">input</span>=<span class="string">&quot;searchText = $event.target.value&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 修饰符，可多个同时使用 --&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- v-model.lazy  失去焦点时绑定 防抖--&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- v-model.number  自动将值转换为数字（vue2 中即使input type设置成number 依然会被转成字符串）--&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- v-model.trim 去除首位空格--&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--多选框中，v-model绑定的是一个数组列表，需要额外设置每一项的value --&gt;</span></span><br><span class="line"><span class="comment">&lt;!--单选框中，需要用相同的 name 关联 ，v-model如果绑定同一个data,就可以不需要name了 ，需要额外设置value --&gt;</span></span><br><span class="line"><span class="comment">&lt;!--select中，直接给select标签v-model,value全在option中 --&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  v-model 在组件上使用</p>
</blockquote>
<p>条件渲染</p>
<blockquote>
<p>  这些指令最好加到 <code>template</code> 元素中, 这样就不会渲染到页面，类似小程序的<code>block</code></p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * v-if/vi-else-if/v-else 节点的删除创建</span></span><br><span class="line"><span class="comment"> * v-show  // display 的显示隐藏</span></span><br><span class="line"><span class="comment"> * v-for=&quot;(item,index) in array&quot;  </span></span><br><span class="line"><span class="comment"> * v-for=&quot;(item, key,index) in object&quot;	</span></span><br><span class="line"><span class="comment"> * 	可迭代对象如字符串都是可以遍历的</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  数组更新的检测，只有改变原数组，或调用可改变元素组的方法，才会更新</p>
</blockquote>
<p>key</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * v-for key 属性的作用</span></span><br><span class="line"><span class="comment"> * 	  唯一的，一般用id </span></span><br><span class="line"><span class="comment"> *	  主要用在Vue的虚拟DOM算法，在新旧nodes对比时辨识VNodes</span></span><br><span class="line"><span class="comment"> *    没使用key，有一种算法，使用key会用一种更好的算法（基于key的变化重新排列元素顺序，并移除不存在的元素）</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<ul>
<li><p>VNode: <code>Virtual Node</code> 虚拟节点</p>
<ul>
<li>位置： 存在于 vue template  到  真实DOM之间</li>
<li>本质：是一个JavaScript对象</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// template: &lt;div class=&quot;title&quot; style=&quot;font-size:30px&quot;&gt;&#123;&#123;msg&#125;&#125;&lt;/div&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> vnode = &#123;</span><br><span class="line">    <span class="attr">type</span>:<span class="string">&quot;div&quot;</span>,</span><br><span class="line">    <span class="attr">props</span>: &#123;</span><br><span class="line">        <span class="attr">class</span>: <span class="string">&quot;title&quot;</span>,</span><br><span class="line">        <span class="attr">style</span>: &#123;</span><br><span class="line">            <span class="string">&quot;font-size&quot;</span>:<span class="string">&quot;30px&quot;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="attr">children</span>: <span class="string">&quot;内容&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// DOM: &lt;div class=&quot;title&quot; style=&quot;font-size:30px&quot;&gt;内容&lt;/div&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>虚拟DOM：很多<code>VNode</code>形成的 <code>VNode Tree</code></p>
<ul>
<li><p>方便跨平台</p>
<ul>
<li>可以转 真实DOM对象</li>
<li>可以转 移动端的 <code>button/view/image</code></li>
<li>可以转 IOS <code>UIButtono/UIView</code></li>
<li><code>JavaScript</code> ，是<strong>脚本语言</strong>，可以将 转换为<strong>各个平台想要显示的东西</strong></li>
</ul>
</li>
<li><p>方便diff算法 </p>
<ul>
<li><strong>没有Key</strong> ：当遍历的<strong>数组发生变化</strong>时，<strong>销毁所有</strong>的<strong>虚拟DOM</strong>，在按照新的数据<strong>全部重新创建</strong></li>
</ul>
<p><img src= "" data-lazy-src="/../../../static/img/not-key.jpg"></p>
<ul>
<li><strong>存在唯一Key</strong>：虚拟DOM会<strong>通过key</strong>认识，<strong>变化后的某个节点，就是变化前的那个节点</strong>，不销毁进行重新排序</li>
</ul>
<p><img src= "" data-lazy-src="/../../../static/img/has-key.jpg"></p>
</li>
</ul>
</li>
</ul>
<h4 id="MVC-与-MVVM"><a href="#MVC-与-MVVM" class="headerlink" title="MVC 与 MVVM"></a>MVC 与 MVVM</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * MVC: `Model - View - Controller` 的简称，（前端也符合，html view - js 控制器）</span></span><br><span class="line"><span class="comment"> *     准备好界面  控制器去服务器获取数据  得到数据转换为模型给页面使用</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * MVVM: `Model（script，data等） - View（template） - ViewModel（Vue框架`） 的简称 ，Vue给Model和View建立桥梁 </span></span><br><span class="line"><span class="comment"> *     ViewModel 把 Model数据 绑定到界面</span></span><br><span class="line"><span class="comment"> *     ViewModel 把 View事件 监听到 Model</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>



<h4 id="组件化"><a href="#组件化" class="headerlink" title="组件化"></a>组件化</h4><ul>
<li>初始化 App 就是根组件，一个vue项目就是一棵组件树</li>
<li>单向数据流  -&gt; 子组件不能直接修改props的数据，如果非要修改，父组件监听子组件emit，在父组件中修改</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义一个全局组件</span></span><br><span class="line"><span class="keyword">const</span> productItem = &#123;</span><br><span class="line">    <span class="attr">template</span>: <span class="string">`&lt;h1&gt;组件&lt;/h1&gt;`</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 注册一个全局组件，组件名称 短横线 或 大驼峰命名</span></span><br><span class="line">app.<span class="title function_">component</span>(<span class="string">&quot;product-item&quot;</span>,productItem);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注册局部组件, 选项components</span></span><br><span class="line"><span class="attr">components</span>:&#123;</span><br><span class="line">    productItem</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  组件通信</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--父组件传递与接收 组件标签通过--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">cpn-name</span> <span class="attr">:name</span>=<span class="string">&#x27;name&#x27;</span> <span class="attr">:info</span>=<span class="string">&quot;InfoObj&quot;</span> @<span class="attr">receive</span>=<span class="string">&quot;xxxx&quot;</span> <span class="attr">:vis</span>=<span class="string">&#x27;a&#x27;</span> <span class="attr">abc</span>=<span class="string">&#x27;123&#x27;</span> &gt;</span><span class="tag">&lt;/<span class="name">cpn-name</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 接收 prop 属性接收 ，横杆和驼峰命名都可以</span></span><br><span class="line"><span class="comment">// 父级传递 没用prop接收的属性，会变成组件中根节点的属性</span></span><br><span class="line"><span class="comment">// 使用 inheritAttrs:false 选项禁止, 也能手动在子节点上 通过 $attrs.abc 给其他子节点</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">props</span>:[<span class="string">&quot;name&quot;</span>], </span><br><span class="line">    <span class="attr">props</span>:&#123;</span><br><span class="line">        <span class="attr">name</span>: &#123;</span><br><span class="line">            <span class="attr">type</span>: <span class="title class_">String</span>,</span><br><span class="line">            <span class="attr">default</span>: <span class="string">&quot;&quot;</span>,</span><br><span class="line">            <span class="attr">required</span>: <span class="literal">true</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="title class_">InfoObj</span>: &#123; <span class="comment">// 对象或数字默认值必须从函数中返回</span></span><br><span class="line">            <span class="attr">type</span>: <span class="title class_">Object</span>,</span><br><span class="line">            <span class="attr">default</span>: <span class="function">()=&gt;</span>&#123; </span><br><span class="line">                <span class="keyword">return</span> &#123;<span class="attr">a</span>:<span class="number">1</span>&#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">vis</span>: &#123; <span class="comment">// 自定义验证</span></span><br><span class="line">            <span class="title function_">validator</span>(<span class="params">value</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> [<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;c&#x27;</span>].<span class="title function_">includes</span>(value)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">emits</span>:[<span class="string">&#x27;receive&#x27;</span>], <span class="comment">// 注册一下，外面用的时候会有提示,也可以验证函数返回</span></span><br><span class="line">	<span class="title function_">mounted</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">this</span>.$emit(<span class="string">&quot;receive&quot;</span>,data) <span class="comment">//子传父</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  非父子组件通信 </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Provide 和 Inject 依赖注入</span></span><br><span class="line"><span class="comment"> *     无论层级多深，父组件都可以通过 Provide 向它下面所有子组件提供数据</span></span><br><span class="line"><span class="comment"> *     子组件通过inject接收</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="title function_">data</span>(<span class="params"></span>)&#123;</span><br><span class="line">        retrun &#123;</span><br><span class="line">            <span class="attr">name</span>:<span class="string">&quot;liao&quot;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">provide</span>: &#123;</span><br><span class="line">        <span class="attr">name</span>:<span class="string">&quot;liao&quot;</span>,</span><br><span class="line">        <span class="attr">age</span>:<span class="number">16</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">provide</span>(<span class="params"></span>)&#123; <span class="comment">// 通过行数使用动态数据，数据改变不会更新</span></span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            <span class="attr">name</span>: <span class="variable language_">this</span>.<span class="property">name</span>,</span><br><span class="line">            <span class="attr">age</span>:<span class="number">16</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">provide</span>(<span class="params"></span>)&#123; <span class="comment">// 通过行数使用动态数据，数据改变更新</span></span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            <span class="attr">name</span>: <span class="title function_">computed</span>(<span class="function">()=&gt;</span> <span class="variable language_">this</span>.<span class="property">name</span>), <span class="comment">// computed 需要从vue引入， 子组件中需要 this.name.value 展示</span></span><br><span class="line">            <span class="attr">age</span>:<span class="number">16</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">inject</span>: [<span class="string">&quot;name&quot;</span>,<span class="string">&quot;age&quot;</span>]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 事件总线</span></span><br><span class="line"><span class="comment"> *    mitt 或 tiny-emitter 库，Vue2 是有自带的 </span></span><br><span class="line"><span class="comment"> *    全局 导入总线对象 EventBusxxx</span></span><br><span class="line"><span class="comment"> *    需要用的地方导入 EventBusxxx，EventBusxxx.emit(&quot;EventName&quot;,data); 发出事件</span></span><br><span class="line"><span class="comment"> *    需要用的地方导入 EventBusxxx，EventBusxxx.on(&quot;EventName&quot;,(data)=&gt;&#123;console.log(data)&#125;); 监听事件</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 状态管理库 vuex</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  组件的生命周期（生命开始到结束经历变化的一系列过程）</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 1、创建  ---  beforeCreate、 created  （创建好后这里有一个 从 html模板编译到虚拟DOM的过程）</span></span><br><span class="line"><span class="comment"> *     发送网络请求、事件监听</span></span><br><span class="line"><span class="comment"> * 2、挂载到组件树（虚拟DOM） --- beforeMount、 mounted （挂到虚拟DOM后，同时将映射到真实DOM，界面上就可以看到）</span></span><br><span class="line"><span class="comment"> *     获取/使用DOM</span></span><br><span class="line"><span class="comment"> * 3、修改更新数据 --- beforeUpdate、 updated （根据新数据生成新VNode,形成新的虚拟DOM，根据diff算法更新真实DOM）</span></span><br><span class="line"><span class="comment"> * 4、卸载 --- beforeUnmount、unmounted （通过v-if可以卸载）</span></span><br><span class="line"><span class="comment"> *     回收操作，取消定时器/事件监听</span></span><br><span class="line"><span class="comment"> * 特殊阶段</span></span><br><span class="line"><span class="comment"> *     缓存组件的生命周期</span></span><br><span class="line"><span class="comment"> *     activated()&#123;&#125;, 激活</span></span><br><span class="line"><span class="comment"> *     deactivated()&#123;&#125; 离开    </span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 我们可以在经历某个阶段做特定的逻辑代码</span></span><br><span class="line"><span class="comment"> * 我们可以通过生命周期函（钩子函数、回调函数）数知道所在的阶段</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  ref  属性绑定DOM或组件实例，this.$refs.xxx 获取实例 </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">this</span>.<span class="property">$refs</span>.<span class="property">cpnRefName</span> <span class="comment">// 直接操作组件里的dom、方法等</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">$refs</span>.<span class="property">cpnRefName</span>.<span class="property">$el</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// this.$paren、this.$root 、this.$children 操作父组件、根组件、子组件（vue 2）</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  动态组件</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;!-- 全局或局部注册的组件 v-for cpnList 内部--&gt;</span><br><span class="line">        &lt;components :is=&quot;cpnList[index]&quot;&gt;&lt;/components&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">export default &#123;</span><br><span class="line">	data()&#123;</span><br><span class="line">		cpnList:[cpn1,cpn2,cpn3]</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  keep-alive 组件切换保持存活，缓存数据</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;!--根据组件name,只缓存这包含的组件 或 exclude=&quot;cpn1&quot; 排除 --&gt;</span><br><span class="line">        &lt;!-- max=3 最多缓存3个 --&gt;</span><br><span class="line">        &lt;keep-alive include=&quot;cpn2,cpn3&quot;&gt; </span><br><span class="line">        	&lt;cpn1&gt;&lt;/cpn1&gt;</span><br><span class="line">    	&lt;/keep-alive&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">export default &#123;</span><br><span class="line">	data()&#123;</span><br><span class="line"></span><br><span class="line">	&#125;,</span><br><span class="line">    components:&#123;</span><br><span class="line">        cpn1,</span><br><span class="line">        cpn2,</span><br><span class="line">        cpn3</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line">    </span><br><span class="line">// 组件内部</span><br><span class="line">activated()&#123;&#125;,</span><br><span class="line">deactivated()&#123;&#125; </span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  异步组件</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span>(<span class="string">&quot;./components/cpn1.vue&quot;</span>).<span class="title function_">then</span>(<span class="function"><span class="params">res</span>=&gt;</span>&#123;&#125;) <span class="comment">// 可以对导入的文件进行分包处理 ,打包成单独文件</span></span><br><span class="line"># vue 异步引入组件</span><br><span class="line"><span class="keyword">import</span> &#123; defineAsyncComponent &#125; <span class="keyword">from</span> <span class="string">&quot;vue&quot;</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Cpn1</span> = <span class="title function_">defineAsyncComponent</span>(<span class="function">()=&gt;</span> <span class="keyword">import</span>(<span class="string">&quot;./components/cpn1.vue&quot;</span>))</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  组件 v-model </p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;cpn1 v-model=&quot;msg&quot;&gt;&lt;/cpn1&gt; </span><br><span class="line">        &lt;cpn1 :model-value=&quot;msg&quot; @update:model-value=&quot;xxx&quot;&gt;&lt;/cpn1&gt;</span><br><span class="line">        </span><br><span class="line">        &lt;cpn1 v-model:msg2=&quot;msg2&quot;&gt;&lt;/cpn1&gt; </span><br><span class="line">        &lt;cpn1 :msg2=&quot;msg2&quot; @update:msg2=&quot;msg2=xxx&quot;&gt;&lt;/cpn1&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">export default &#123;</span><br><span class="line">	data()&#123;</span><br><span class="line">		msg:&quot;123&quot;,</span><br><span class="line">        msg2:&quot;456&quot;</span><br><span class="line">	&#125;,</span><br><span class="line">    components:&#123;</span><br><span class="line">        cpn1,</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  Mixin 混入 (不常用)</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 多组件、页面都需要用的方法、属性统一抽取</span></span><br><span class="line"><span class="comment">// 单独js 文件 mixin.js 定义一些东西</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="title function_">data</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            <span class="attr">msg</span>:<span class="number">123</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">created</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">msg</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">methods</span>:&#123;</span><br><span class="line">        <span class="title function_">showMsg</span>(<span class="params"></span>)&#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">msg</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 单独引入</span></span><br><span class="line"><span class="keyword">import</span> msgmixin <span class="keyword">from</span> <span class="string">&quot;../xxx/mixin&quot;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">mixins</span>:[msgmixin], <span class="comment">// 使用，组件中的东西会和mixin合并，如果名字一样，组件中覆盖mixin</span></span><br><span class="line">    <span class="title function_">mounted</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="title function_">showMsg</span>(); </span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> </span><br></pre></td></tr></table></figure>



<h4 id="插槽"><a href="#插槽" class="headerlink" title="插槽"></a>插槽</h4><blockquote>
<p>  渲染作用域：插槽所有内容都是父组件里的数据</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 普通插槽父组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">cpn-item</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span>&gt;</span>普通插槽内容<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">cpn-item</span>&gt;</span> </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 子组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span>&gt;</span> </span><br><span class="line">        <span class="tag">&lt;<span class="name">slot</span>&gt;</span><span class="tag">&lt;<span class="name">h1</span>&gt;</span>没使用插槽默认展示<span class="tag">&lt;/<span class="name">h1</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span> <span class="comment">&lt;!--&lt;button&gt;普通插槽内容&lt;/button&gt; 插入这里name=&quot;default&quot;--&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 具名插槽父组件 v-slot:[可以是变量] #warp--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">cpn-item</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">template</span> <span class="attr">v-slot:warp</span>&gt;</span></span><br><span class="line">    	<span class="tag">&lt;<span class="name">button</span>&gt;</span>外面<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">template</span> <span class="attr">v-slot:inner</span>&gt;</span></span><br><span class="line">    	<span class="tag">&lt;<span class="name">button</span>&gt;</span>里面<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">cpn-item</span>&gt;</span> </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 子组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;warp&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;inner&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 数据向外传递 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">cpn-item</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">template</span> <span class="attr">v-slot:default</span>=<span class="string">&quot;props&quot;</span>&gt;</span> <span class="comment">&lt;!--只有默认的，可以简写成 v-slot=&quot;props&quot; 或 #default=&quot;props&quot;--&gt;</span></span><br><span class="line">    	<span class="tag">&lt;<span class="name">button</span>&gt;</span>&#123;&#123;props.item&#125;&#125; - &#123;&#123;props.title&#125;&#125;<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">cpn-item</span>&gt;</span> </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- 子组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span>&gt;</span> </span><br><span class="line">        <span class="tag">&lt;<span class="name">slot</span> <span class="attr">:item</span>=<span class="string">&quot;item&quot;</span> <span class="attr">title</span>=<span class="string">&#x27;name&#x27;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="Composition-Api-（组合API）"><a href="#Composition-Api-（组合API）" class="headerlink" title="Composition Api （组合API）"></a>Composition Api （组合API）</h2><blockquote>
<p>  将data数据，监听数据，方法数据，需要用到的组合起来完成，放在一个地方，选项API逻辑太过分散</p>
</blockquote>
<blockquote>
<p>  组合在一起 抽取封装方便 (hooks)</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义一个 hook  useCount.js</span></span><br><span class="line"><span class="keyword">import</span> &#123; ref &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">useCounter</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">let</span> counter = <span class="title function_">ref</span>(<span class="number">100</span>);</span><br><span class="line">    <span class="keyword">const</span> <span class="title function_">increment</span> = (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">        counter.<span class="property">value</span>++;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(counter.<span class="property">value</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">const</span> <span class="title function_">decrement</span> = (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">        counter.<span class="property">value</span>--</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> &#123; counter, increment, decrement&#125;  </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 组件中引用</span></span><br><span class="line"><span class="keyword">import</span> useCounter <span class="keyword">from</span> <span class="string">&quot;./hooks/useCounter&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">const</span> &#123; counter, increment, decrement &#125; = <span class="title function_">useCounter</span>();</span><br><span class="line">        <span class="keyword">return</span> &#123; <span class="comment">// 直接就能用复用</span></span><br><span class="line">            counter, </span><br><span class="line">            increment,</span><br><span class="line">            decrement</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<blockquote>
<p>  函数式变成思想，以前对象里的功能转变为函数的调用</p>
</blockquote>
<p>setup</p>
<ol>
<li><code>setup</code> 无this</li>
<li><strong>两个属性</strong>：props 存放父组件传递的参数，context 有 <code>attrs、slots、emit</code></li>
<li>template 需要用的东西 需要从setup中 <code>return</code> 出去</li>
<li>setup 内部使用变量需要加 .value  ,retrun 到 template 中的不需要写 .value</li>
</ol>
<h4 id="Setup-上下文"><a href="#Setup-上下文" class="headerlink" title="Setup 上下文"></a>Setup 上下文</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 透传 Attributes（非响应式的对象，等价于 $attrs）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(context.<span class="property">attrs</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 插槽（非响应式的对象，等价于 $slots）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(context.<span class="property">slots</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 触发事件（函数，等价于 $emit）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(context.<span class="property">emit</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 暴露公共属性（函数）,父组件通过ref得到子组件实例，仅能访问expose的内容</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(context.<span class="property">expose</span>)</span><br></pre></td></tr></table></figure>



<h4 id="Setup-实现-data-数据"><a href="#Setup-实现-data-数据" class="headerlink" title="Setup 实现 data  数据"></a>Setup 实现 data  数据</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;!-- vue 自动将count ref对象解包 不能带value，深层对象修改时需要带.value --&gt;</span><br><span class="line">        &#123;&#123; count &#125;&#125;</span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            &#123;&#123; infos.username &#125;&#125;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">import &#123; ref, reactive &#125; from &#x27;vue&#x27;;</span><br><span class="line">export default &#123;</span><br><span class="line">    name: &quot;TestPage&quot;,</span><br><span class="line">    setup() &#123;</span><br><span class="line">        // ref 简单响应式数据,也可以是复杂类型数据</span><br><span class="line">        let count = ref(100); // count 对应 ref对象的value</span><br><span class="line">        count.value++;</span><br><span class="line">        console.log(count.value);</span><br><span class="line">        </span><br><span class="line">        let data = ref([]); // 网络请求数据，默认[]</span><br><span class="line">        const res = [&#123;a:1&#125;,&#123;b:2&#125;]</span><br><span class="line">        data.value = res;</span><br><span class="line">        console.log(data.value);</span><br><span class="line"></span><br><span class="line">        // reactive 复杂数据类型依赖收集, 不要关心value</span><br><span class="line">        const infos = reactive(&#123;</span><br><span class="line">            username: &#x27;lzoxun&#x27;,</span><br><span class="line">            passwd: &#x27;123456&#x27;</span><br><span class="line">        &#125;)</span><br><span class="line">        infos.username = &quot;abc&quot;;</span><br><span class="line">        </span><br><span class="line">        // readonly 只读代理 普通/ref/reactive对象都能传入</span><br><span class="line">        const readonlys = readonly(infos)</span><br><span class="line">        readonlys.username = &quot;456&quot;; // 无法修改</span><br><span class="line"></span><br><span class="line">        return &#123;</span><br><span class="line">            count,</span><br><span class="line">            data,</span><br><span class="line">            readonlys,</span><br><span class="line">            infos</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  响应式数据相关工具方法</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">isProxy <span class="comment">// 检测数据是否由reactive或readonly穿件的proxy</span></span><br><span class="line">isReactave <span class="comment">// 检测是否由reactive创建的响应式代理，readonly包裹reactive对象创建的也会返回true</span></span><br><span class="line">isReadonly <span class="comment">// 是否有有readonly创建的只读代理 </span></span><br><span class="line">isRef  <span class="comment">// 数据是否有ref创建</span></span><br><span class="line"></span><br><span class="line">shallowReactive <span class="comment">// 浅层作用: 一级属性可以响应式，但深层的不可以，只是普通数据</span></span><br><span class="line">shallowReadonly <span class="comment">// 浅层作用：一级属性无法修改，但深层的可以</span></span><br><span class="line">shallowRef</span><br><span class="line"></span><br><span class="line">toRaw <span class="comment">// 返回 reactive 或 readonly 代理的原始对象，去除Proxy效果</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> &#123; username, passwd &#125; = <span class="title function_">toRefs</span>(infos) <span class="comment">// 结构reactive数据, 成 ref数据</span></span><br><span class="line"><span class="keyword">const</span> username = <span class="title function_">toRef</span>(infos,<span class="string">&#x27;username&#x27;</span>) <span class="comment">//结构单个</span></span><br><span class="line"><span class="keyword">const</span> uncount = <span class="title function_">unref</span>(count) <span class="comment">// isRef(val) ? val.val : val;</span></span><br><span class="line"></span><br><span class="line"><span class="title function_">triggerRef</span>(count) <span class="comment">// 特殊情况改变完没有响应，手动强制响应</span></span><br></pre></td></tr></table></figure>

<h4 id="Setup-实现-计算属性"><a href="#Setup-实现-计算属性" class="headerlink" title="Setup 实现 计算属性"></a>Setup 实现 计算属性</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; ref, computed &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;TestPage&quot;</span>,</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">const</span> count = <span class="title function_">ref</span>(<span class="number">1</span>)</span><br><span class="line">        <span class="keyword">const</span> plusOne = <span class="title function_">computed</span>(<span class="function">() =&gt;</span> count.<span class="property">value</span> + <span class="number">1</span>)  <span class="comment">// 计算属性也是一个  ref</span></span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(plusOne.<span class="property">value</span>) <span class="comment">// 2</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            plusOne </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Setup-实现-生命周期"><a href="#Setup-实现-生命周期" class="headerlink" title="Setup 实现 生命周期"></a>Setup 实现 生命周期</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;TestPage&quot;</span>,</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">// setup 本身 取代了 created 和 beforeCreated 这连个生命周期</span></span><br><span class="line">        </span><br><span class="line">        <span class="title function_">onBeforeMount</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 组件挂载之前</span></span><br><span class="line">        <span class="title function_">onMounted</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 组件挂载完成执行</span></span><br><span class="line">        </span><br><span class="line">        <span class="title function_">onBeforeUpdate</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 响应式数据变更之前</span></span><br><span class="line">        onUpdated (<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 响应式数据变更</span></span><br><span class="line">        </span><br><span class="line">        <span class="title function_">onBeforeUnmount</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 组件十六卸载之前</span></span><br><span class="line">        <span class="title function_">onUnmounted</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// 组件实例被卸载</span></span><br><span class="line">        </span><br><span class="line">        <span class="title function_">onActivated</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// &lt;KeepAlive&gt; 的组件激活</span></span><br><span class="line">        <span class="title function_">onDeactivated</span>(<span class="function">()=&gt;</span>&#123;&#125;) <span class="comment">// &lt;KeepAlive&gt; 的组件卸载</span></span><br><span class="line">        </span><br><span class="line">        <span class="title function_">onErrorCaptured</span>(<span class="function">()=&gt;</span>&#123;&#125;) </span><br><span class="line">        <span class="title function_">onRenderTracked</span>(<span class="function">()=&gt;</span>&#123;&#125;) </span><br><span class="line">        <span class="title function_">onRenderTriggered</span>(<span class="function">()=&gt;</span>&#123;&#125;) </span><br><span class="line">        <span class="title function_">onServerPrefetch</span>(<span class="function">()=&gt;</span>&#123;&#125;) </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  ref  获取 dom 节点</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">	&lt;div ref=&#x27;titleRef&#x27;&gt;标题&lt;/div&gt;</span><br><span class="line">	&lt;button ref=&#x27;btnRef&#x27;&gt;按钮&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">	export default &#123;</span><br><span class="line">        setup()&#123;</span><br><span class="line">            const titleRef = ref();</span><br><span class="line">            const btnRef = ref();</span><br><span class="line">            </span><br><span class="line">            onMounted(()=&gt;&#123;</span><br><span class="line">                console.log(titleRef.value)</span><br><span class="line">                console.log(btnRef.value)</span><br><span class="line">            &#125;)</span><br><span class="line">            </span><br><span class="line">            return &#123; // 一定要 return </span><br><span class="line">                btnRef, </span><br><span class="line">                titleRef</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>



<h4 id="Setup-实现-Provide-Inject"><a href="#Setup-实现-Provide-Inject" class="headerlink" title="Setup 实现 Provide&#x2F;Inject"></a>Setup 实现 Provide&#x2F;Inject</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; ref, provide &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;TestPage&quot;</span>,</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">// 提供静态值</span></span><br><span class="line">        <span class="title function_">provide</span>(<span class="string">&#x27;foo&#x27;</span>, <span class="string">&#x27;bar&#x27;</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 提供响应式的值</span></span><br><span class="line">        <span class="keyword">const</span> count = <span class="title function_">ref</span>(<span class="number">0</span>)</span><br><span class="line">        <span class="title function_">provide</span>(<span class="string">&#x27;count&#x27;</span>, count)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 下级组件中</span></span><br><span class="line"><span class="keyword">import</span> &#123; ref, inject &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;TestPage&quot;</span>,</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">// 注入值的默认方式</span></span><br><span class="line">        <span class="keyword">const</span> foo = <span class="title function_">inject</span>(<span class="string">&#x27;foo&#x27;</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 注入响应式的值</span></span><br><span class="line">        <span class="keyword">const</span> count = <span class="title function_">inject</span>(<span class="string">&#x27;count&#x27;</span>,<span class="string">&#x27;default value&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Setup-实现-watch-watchEffect"><a href="#Setup-实现-watch-watchEffect" class="headerlink" title="Setup 实现 watch&#x2F;watchEffect"></a>Setup 实现 watch&#x2F;watchEffect</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; ref, watch, watchEffect &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&quot;TestPage&quot;</span>,</span><br><span class="line">    <span class="title function_">setup</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">const</span> message = <span class="title function_">ref</span>(<span class="string">&quot;hello word&quot;</span>);</span><br><span class="line">        <span class="title function_">watch</span>(message,<span class="function">(<span class="params">n,o</span>)=&gt;</span>&#123; <span class="comment">// [msg1,msg2] 可以监听多个</span></span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(n,o)</span><br><span class="line">        &#125;,&#123;</span><br><span class="line">            <span class="attr">immediate</span>:<span class="literal">true</span>, <span class="comment">// 先执行一次</span></span><br><span class="line">            <span class="attr">deep</span>:<span class="literal">true</span> <span class="comment">// 深度监听，默认true</span></span><br><span class="line">        &#125;) </span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">        <span class="title function_">watch</span>(<span class="function">()=&gt;</span> (&#123;...infos&#125;),<span class="function">(<span class="params">n,o</span>)=&gt;</span>&#123; <span class="comment">// 自动收集infos 里面的所有依赖，不加小括号,大括号会被当成代码块</span></span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(n,o)</span><br><span class="line">        &#125;,&#123;</span><br><span class="line">             <span class="attr">deep</span>:<span class="literal">true</span>  </span><br><span class="line">        &#125;)</span><br><span class="line">        </span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 里面的函数自动被执行</span></span><br><span class="line"><span class="comment">         * 函数内部涉及到的依赖会被自动收集，只要监听到一个发生变化，就自动再次执行这个函数</span></span><br><span class="line"><span class="comment">         * 返回值 调用就停止监听了</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="keyword">const</span> stopWatchxx = <span class="title function_">watchEffect</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            </span><br><span class="line">        &#125;) </span><br><span class="line">        </span><br><span class="line">        <span class="keyword">return</span> &#123;</span><br><span class="line">            message</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Setup-script语法糖"><a href="#Setup-script语法糖" class="headerlink" title="Setup script语法糖"></a>Setup script语法糖</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--</span><br><span class="line">	1、引入组件直接使用不需要注册</span><br><span class="line">    2、顶层（非函数内）的代码默认暴露给template，可以直接使用不需要return</span><br><span class="line">    3、defineProps(&#123;&#125;),代替props定义 组件接收的数据（setup语法中直接用，不需要引入）</span><br><span class="line">    4、defineEmits([&quot;infoBtnClick&quot;]) </span><br><span class="line">    5、defineExports  暴露属性或方法到组件外（通过ref拿到组件时可以调用暴露出的方法）</span><br><span class="line">--&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">	const message = ref(&quot;msg&quot;) // 不要 return 就可以直接使用</span><br><span class="line">    </span><br><span class="line">    const props = defineProps(&#123;</span><br><span class="line">        title:&#123;</span><br><span class="line">            type:String,</span><br><span class="line">            default:&quot;首页&quot;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">    const emits = defineEmits([&quot;infoBtnClick&quot;]);</span><br><span class="line">    function showInfoBtnClick() &#123;</span><br><span class="line">        emits(&quot;infoBtnClicks&quot;,&quot;data&quot;)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    // 暴露方法</span><br><span class="line">    function foo()&#123;</span><br><span class="line">    	console.log(&quot;foo &quot;)</span><br><span class="line">    &#125;</span><br><span class="line">    defineExports(&#123;</span><br><span class="line">        foo</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h2 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h2><p>路由名称来源于网络架构的<strong>路由器</strong>，<strong>路由器</strong>主要维护着一个<strong>映射表</strong>，<strong>映射表</strong>会绝对数据的流向</p>
<p>路由器映射表<strong>存放</strong> 它分配的 <strong>IP地址 –&gt; 目标设备mac地</strong>址 的关系映射表（每个硬件设备都有一个独一无二的固定的 mac 地址）</p>
<blockquote>
<p>后端路由</p>
</blockquote>
<p>后端维护着 <strong>不同URL –&gt; 对应页面</strong> 的关系<strong>映射表</strong>，后端<strong>根据不同URL</strong>，渲染出<strong>不同的页面</strong>，<strong>整个页面</strong>返回给客户端</p>
<p>后端维护着 <strong>不同API –&gt; 对应数据</strong> 的关系<strong>映射表</strong>，后端<strong>根据不同API</strong>，整理出<strong>不同的数据</strong>，再把<strong>数据</strong>返回给客户端</p>
<blockquote>
<p>  前端路由</p>
</blockquote>
<p>来源于 <strong>SPA</strong> 单页面应用，在前后端分离的情况下，前端自己实现显示更换</p>
<p>前端来维护 不<strong>同URL –&gt; 对应组件</strong> 的关系 <strong>映射表</strong>，前端<strong>根据不同URL</strong>，渲染<strong>不同组件</strong></p>
<p>改变URL 页面不刷新的两种模式</p>
<p>​		<strong>hash实现</strong> ：监听 hashchange 事件时，就可以不刷新页面，而去做一些事情</p>
<p>​		<strong>history实现</strong> pushState、replaceState 等方法切换路径，可以修改url而不刷新页面</p>
<hr>
<h3 id="vue-router"><a href="#vue-router" class="headerlink" title="vue-router"></a>vue-router</h3><blockquote>
<p>  下载包  –&gt; 导入 –&gt; 创建 –&gt; 选择模式 –&gt; 设置映射表    app.use</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// router.js</span></span><br><span class="line"><span class="keyword">import</span> &#123; createRouter, createWebHashHistory &#125; <span class="keyword">from</span> <span class="string">&quot;vue-router&quot;</span>; </span><br><span class="line"><span class="keyword">const</span> router = <span class="title function_">createRouter</span>(&#123;</span><br><span class="line">    <span class="attr">history</span>: <span class="title function_">createWebHashHistory</span>(), <span class="comment">// createWebHistory() history 模式</span></span><br><span class="line">    <span class="attr">routes</span>:[</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 默认替换到App.vue 的 &lt;router-view&gt; 位置</span></span><br><span class="line">            <span class="attr">path</span>:<span class="string">&quot;/home&quot;</span>,</span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * import 实现懒加载</span></span><br><span class="line"><span class="comment">             * import 打包分包，用户只要一个页面，没必要把下载所有组件，全在app.js文件中就全部都要下载了</span></span><br><span class="line"><span class="comment">             * 魔法注释，分包后的包名</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="attr">component</span>:<span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="comment">/* webpackChunkName: &#x27;home&#x27; */</span> <span class="string">&quot;../views/Home.vue&quot;</span>), </span><br><span class="line">            <span class="attr">name</span>:<span class="string">&quot;home&quot;</span>,</span><br><span class="line">            <span class="attr">mate</span>:&#123;&#125;,  <span class="comment">// 自定义数据</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="attr">path</span>:<span class="string">&quot;/pather&quot;</span>,</span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 子路由 </span></span><br><span class="line"><span class="comment">             * 访问: /pather/profile </span></span><br><span class="line"><span class="comment">             * Profile 将被渲染到 Home 的 &lt;router-view&gt; 内部 </span></span><br><span class="line"><span class="comment">             * ???</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="attr">children</span>:[</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="attr">path</span>:<span class="string">&quot;&quot;</span>,</span><br><span class="line">                    <span class="attr">component</span>:<span class="title class_">ChiMain</span></span><br><span class="line">                &#125;,</span><br><span class="line">                &#123; </span><br><span class="line">                    <span class="attr">path</span>:<span class="string">&quot;profile&quot;</span>,</span><br><span class="line">                    <span class="attr">component</span>:<span class="title class_">Profile</span></span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">// 动态路由 js 中通过 $route.params.id 获取</span></span><br><span class="line">            <span class="attr">path</span>:<span class="string">&quot;/user/:id&quot;</span>,</span><br><span class="line">            <span class="attr">component</span>:<span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&quot;../views/User.vue&quot;</span>), </span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;   </span><br><span class="line">            <span class="comment">// 放在最后 $route.params.pathMatch 取到具体的错误路径</span></span><br><span class="line">            <span class="attr">path</span>:<span class="string">&quot;/:pathMatch(.*)&quot;</span>,</span><br><span class="line">            <span class="attr">component</span>:<span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&quot;../views/404.vue&quot;</span>), </span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router;</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.js</span></span><br><span class="line"><span class="keyword">import</span> router <span class="keyword">from</span> <span class="string">&#x27;./router&#x27;</span></span><br><span class="line">app.<span class="title function_">use</span>(router)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过 router-link 和 router-view 跳转 展示组件</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  router-link 和 router-view</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--</span><br><span class="line">	replace 使用 replace 跳转 默认push</span><br><span class="line">	active-class 属性设置激活的class 名称 默认 .router-link active</span><br><span class="line">--&gt;</span><br><span class="line">&lt;router-link to=&#x27;/index&#x27; replace active-class=&#x27;active&#x27;&gt;&lt;/router-link&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;!--</span><br><span class="line">	占位，路由跳转时组件替换</span><br><span class="line">--&gt;</span><br><span class="line">&lt;router-view&gt;&lt;/router-view&gt; </span><br></pre></td></tr></table></figure>

<blockquote>
<p>  $router 和 $route </p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash"><span class="variable">$router</span> 大对象，一般用于路由跳转</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash"><span class="variable">$route</span> 某个路由对象 `this.<span class="variable">$route</span>.path`  `this.<span class="variable">$route</span>.name` 获取单前路由的一些信息，routes映射数组的一个元素</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  setup 中通过 hook函数使用路由</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&lt;script setup&gt;</span><br><span class="line">	const &#123; useRouter, useRoute, onBeforeRouteUpdate &#125; from &#x27;vue-router&#x27;;</span><br><span class="line">    const route = useRoute();</span><br><span class="line">    console.log(route.path)</span><br><span class="line">    console.log(route.params.id)</span><br><span class="line">    </span><br><span class="line">    // 导航守卫</span><br><span class="line">    onBeforeRouteUpdate((to,from)=&gt;&#123;</span><br><span class="line">        </span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">    // 路由跳转</span><br><span class="line">    const router = useRouter();</span><br><span class="line">    router.push(&quot;/home&quot;);</span><br><span class="line">    router.replace(&quot;/home&quot;);</span><br><span class="line">    router.back();</span><br><span class="line">    router.forward();</span><br><span class="line">    router.go(+-n); </span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h4 id="动态配置路由"><a href="#动态配置路由" class="headerlink" title="动态配置路由"></a>动态配置路由</h4><blockquote>
<p>  管理系统中，每个角色<strong>路由</strong>通过<strong>接口获取</strong>，给不同角色，组成不同路由（直接写死的路由实现管理系统，只是普通的菜单显示隐藏）</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// router.js</span></span><br><span class="line"><span class="keyword">import</span> &#123; createRouter, createWebHashHistory &#125; <span class="keyword">from</span> <span class="string">&quot;vue-router&quot;</span>; </span><br><span class="line"><span class="keyword">const</span> router = <span class="title function_">createRouter</span>(&#123;</span><br><span class="line">    <span class="attr">history</span>: <span class="title function_">createWebHashHistory</span>(), </span><br><span class="line">    <span class="attr">routes</span>:[</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="attr">path</span>:<span class="string">&quot;/user/:id&quot;</span>,</span><br><span class="line">            <span class="attr">name</span>:<span class="string">&quot;user&quot;</span>,</span><br><span class="line">            <span class="attr">component</span>:<span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&quot;../views/User.vue&quot;</span>), </span><br><span class="line">        &#125;,</span><br><span class="line">    ]</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> isAdmin = <span class="literal">true</span>; <span class="comment">// 真实环境下等用户登录，判断他有什么角色</span></span><br><span class="line"><span class="keyword">if</span>(isAdmin)&#123;</span><br><span class="line">    router.<span class="title function_">addRoute</span>(&#123;</span><br><span class="line">        <span class="attr">path</span>:<span class="string">&quot;/admin&quot;</span>,</span><br><span class="line">        <span class="attr">name</span>:<span class="string">&quot;admin&quot;</span>,</span><br><span class="line">         <span class="attr">component</span>:<span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&quot;../views/AdminPage.vue&quot;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">// 动态添加二级域名</span></span><br><span class="line">    router.<span class="title function_">addRoute</span>(<span class="string">&quot;home&quot;</span>,&#123;</span><br><span class="line">        </span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  删除路由</span></span><br><span class="line"><span class="comment">     *  1、添加一个重名的路由，覆盖掉要删除的，路由name是唯一的</span></span><br><span class="line"><span class="comment">     *  2、router.removeRoute(&quot;admin&quot;)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 其他一下方法</span></span><br><span class="line">router.<span class="title function_">getRoutes</span>() <span class="comment">// 获取路由</span></span><br><span class="line">router.<span class="title function_">hasRoute</span>() <span class="comment">// 检测路由是否存在</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router;</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.js</span></span><br><span class="line"><span class="keyword">import</span> router <span class="keyword">from</span> <span class="string">&#x27;./router&#x27;</span></span><br><span class="line">app.<span class="title function_">use</span>(router)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  导航守卫，路由拦截 <a target="_blank" rel="noopener" href="https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB">文档</a></p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 1、判断用户是否登录，否则返回登录页面</span></span><br><span class="line"><span class="comment"> * 2、从一个页面跳转到另一个页面做一些事情</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">import</span> &#123; createRouter, createWebHashHistory &#125; <span class="keyword">from</span> <span class="string">&quot;vue-router&quot;</span>; </span><br><span class="line"><span class="keyword">const</span> router = <span class="title function_">createRouter</span>(&#123;</span><br><span class="line">    <span class="attr">history</span>: <span class="title function_">createWebHashHistory</span>(), </span><br><span class="line">    <span class="attr">routes</span>:[]</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 1、任何路由跳转之前都会进入回调</span></span><br><span class="line"><span class="comment"> * 2、to 即将进入的路由对象</span></span><br><span class="line"><span class="comment"> * 3、from 即将离开的路由对象</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">router.<span class="title function_">beforeEach</span>(<span class="function">(<span class="params">to,<span class="keyword">from</span>,next</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(to.<span class="property">path</span> != <span class="string">&#x27;/login&#x27;</span>)&#123;</span><br><span class="line">        retrun <span class="string">&#x27;/login&#x27;</span> <span class="comment">// 返回指定页面，和 router.push 一样</span></span><br><span class="line">        retrun <span class="literal">false</span> <span class="comment">// 取消单前导航</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router;</span><br></pre></td></tr></table></figure>



<h2 id="Vuex"><a href="#Vuex" class="headerlink" title="Vuex"></a>Vuex</h2><p>推荐 <code>options Api</code> 使用</p>
<p>单一状态是，整个项目只有一个<code>store</code>实例</p>
<blockquote>
<p>  状态管理</p>
</blockquote>
<p>全局保存<strong>数据状态(State)<strong>，任何组件都能</strong>共享</strong>和<strong>修改</strong>，</p>
<p>把各个组件中<strong>复杂的状态</strong>抽取到一个公共<strong>store仓库</strong></p>
<p><img src= "" data-lazy-src="/../../../static/img/vuex.png"></p>
<p>1、中间虚线是vuex部分，<strong>State</strong>保存全局<strong>数据</strong>，应用程角度可以<strong>叫做状态</strong></p>
<p>2、<strong>Vue Components</strong> 获取 <strong>State</strong> 数据 <strong>Rander</strong>渲染到页面</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">	&lt;div&gt;&#123;&#123;$store.state.counter&#125;&#125;&lt;/div&gt; &lt;!--模板直接获取状态--&gt;</span><br><span class="line">    &lt;div&gt;&#123;&#123;name&#125;&#125; - &#123;&#123;level&#125;&#125; &lt;/div&gt;</span><br><span class="line">	&lt;div&gt;&lt;/div&gt;</span><br><span class="line">	&lt;button @click=&quot;incr&quot;&gt;&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- options API --&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">import &#123; mapState, mapGetters  &#125; from vuex;</span><br><span class="line">export default &#123;</span><br><span class="line">    componend:&#123;</span><br><span class="line">        ...mapState([&quot;name&quot;,&quot;level&quot;]), // store的state映射过来，得到 name函数 和 level函数 结构到计算属性中</span><br><span class="line">        ...mapState(&#123;</span><br><span class="line">            sName: state =&gt; state.name // 重命名</span><br><span class="line">        &#125;),</span><br><span class="line">        ...mapGetters([&quot;message&quot;]) // 和 mapState 一样</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- composition API --&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">	import &#123; useStore, mapState, toRefs &#125; from &quot;vuex&quot;; // 通过 hook</span><br><span class="line">    </span><br><span class="line">    const store = useStore();</span><br><span class="line">    const &#123; counter &#125; = toRefs(store.state);</span><br><span class="line">    console.log(counter);</span><br><span class="line">    console.log(store.state.counter); // 获取状态无法响应式</span><br><span class="line">    </span><br><span class="line">    const &#123; name &#125; = mapState([&#x27;name&#x27;]) // 得到一个 name 函数 ，可以分组到 hook</span><br><span class="line">    const sName = computed(name.bind(&#123; $store: store&#125;)); //因为内部通过 this.$store.stete.name 获取</span><br><span class="line">     </span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<p>3、<strong>Vue Components</strong> 同 <strong>Dispatch</strong> 触发 <strong>Actions</strong> 异步方法，在Actives调用网络请求 <strong>Backend API</strong> 等异步操作</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 如果存在异步操作 dispatch Actions 从 Actions 提交 mutations --&gt;</span><br><span class="line">&lt;template&gt;</span><br><span class="line">	&lt;div&gt;&#123;&#123;$store.state.level&#125;&#125;&lt;/div&gt; </span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- options API --&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">import &#123; mapActions &#125; from &quot;vuex&quot;;</span><br><span class="line">export default &#123;</span><br><span class="line">   	methods:&#123;</span><br><span class="line">        ...mapActions([&quot;changeLevelAction&quot;]), /* 将store 的 actions 里的方法映射过来 */</span><br><span class="line">        dispatchAction()&#123;</span><br><span class="line">            /* 直接派发 */</span><br><span class="line">            this.$store.dispatch(&quot;changeLevelAction&quot;,&#x27;xun&#x27;);</span><br><span class="line">            </span><br><span class="line">            /* 使用映射过来的方法 */</span><br><span class="line">            this.changeLevelAction(&#x27;xun&#x27;)</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- composition API --&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">	import &#123; useStore, mapActions &#125; from &quot;vuex&quot;; // 通过 hook</span><br><span class="line">    const store = useStore();</span><br><span class="line">    </span><br><span class="line">    /* 映射过来，处理this问题， 内部 this.$store.dispatch */</span><br><span class="line">    const actions = mapActions([&#x27;changeLevelAction&#x27;]);</span><br><span class="line">    const newActions = &#123;&#125;;</span><br><span class="line">    Object.keys(actions).forEach(key=&gt;&#123;</span><br><span class="line">         newActions[key] = actions[key].bind(&#123; $store: store &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">    const &#123; changeLevelAction &#125; = newActions;</span><br><span class="line">    </span><br><span class="line">    function changeState()&#123;</span><br><span class="line">        /* 不使用映射的方法直接调用 */</span><br><span class="line">        store.dispatch(&quot;changeLevelAction&quot;);</span><br><span class="line">        /* 如果返回的是Promise，直接拿到数据, async行数默认返回的就是Promise */</span><br><span class="line">        store.dispatch(&quot;changeLevelAction&quot;).then(res=&gt;&#123;</span><br><span class="line">            console.log(res)</span><br><span class="line">        &#125;);</span><br><span class="line">        </span><br><span class="line">        /* 使用映射过来的方法 */</span><br><span class="line">        changeLevelAction();</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>



<p>4、要求数据必须 <strong>Commit</strong> 提交到 <strong>Mutatios</strong> 中，才能从 <strong>Mutations</strong> 中修改 <strong>State</strong> 的状态</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 如果不存在异步操作 直接提交 mutations --&gt;</span><br><span class="line">&lt;template&gt;</span><br><span class="line">	&lt;div&gt;&#123;&#123;$store.state.counter&#125;&#125;&lt;/div&gt; </span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- options API --&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">import &#123; mapMutations &#125; from &quot;vuex&quot;;</span><br><span class="line">export default &#123;</span><br><span class="line">   	methods:&#123;</span><br><span class="line">        ...mapMutations([&#x27;increment&#x27;,CHANGE_NAME]), /* 将store 的 mutations 里的方法映射过来 */</span><br><span class="line">        changeState()&#123;</span><br><span class="line">            /** </span><br><span class="line">             * increment 名称永远要与 store mutations定义的保持一致</span><br><span class="line">             *  	所有mutations名字经常会被提取到常量中</span><br><span class="line">             */</span><br><span class="line">            this.$store.commit(&quot;increment&quot;,&#x27;lzoxun&#x27;);</span><br><span class="line">            </span><br><span class="line">            /* 使用映射过来的方法 */</span><br><span class="line">            this.increment(&#x27;lzoxun&#x27;)</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- composition API --&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">	import &#123; useStore &#125; from &quot;vuex&quot;; // 通过 hook</span><br><span class="line">    const store = useStore();</span><br><span class="line">    </span><br><span class="line">    /* 映射过来，处理this问题， 内部 this.$store.commit */</span><br><span class="line">    import &#123; mapMutations &#125; from &quot;vuex&quot;;</span><br><span class="line">    const mutations = mapMutations([&#x27;increment&#x27;]);</span><br><span class="line">    const newMutations = &#123;&#125;;</span><br><span class="line">    Object.keys(mutations).forEach(key=&gt;&#123;</span><br><span class="line">         newMutations[key] = mutations[key].bind(&#123; $store: store &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">    const &#123; incrment &#125; = newMutations;</span><br><span class="line">    </span><br><span class="line">    function changeState()&#123;</span><br><span class="line">        store.commit(&quot;increment&quot;); // 直接commit mutations,从mutations的 increment 修改数据</span><br><span class="line">        </span><br><span class="line">        /* 使用映射过来的方法 */</span><br><span class="line">        incrment();</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>



<p>5、<strong>Mutations</strong> 中修改 <strong>State</strong> 的状态可以受到 <strong>Devtools</strong> 工具跟踪，直接修改也能成功，但工具无法跟踪</p>
<p>6、<strong>Modules</strong> 的使用</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* store/modules/home.js */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="attr">namespaced</span>:<span class="literal">true</span>,</span><br><span class="line">    <span class="title function_">state</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="attr">name</span>:<span class="string">&quot;123&quot;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">getters</span>:&#123;</span><br><span class="line">        <span class="title function_">homeGetter</span>(<span class="params">state,getters,rootState</span>)&#123;&#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">mutations</span>:&#123;</span><br><span class="line">        <span class="title function_">homeMutation</span>(<span class="params">state</span>)&#123;&#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">actions</span>:&#123;&#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* store 中导入module */</span></span><br><span class="line"><span class="keyword">import</span> homeModule form <span class="string">&quot;./modules/home&quot;</span>;</span><br><span class="line"><span class="keyword">const</span> store = <span class="title function_">createStore</span>(&#123;</span><br><span class="line">    <span class="title function_">state</span>(<span class="params"></span>)&#123;&#125;,</span><br><span class="line">    <span class="attr">getters</span>:&#123;&#125;,</span><br><span class="line">    <span class="attr">mutations</span>:&#123;&#125;,</span><br><span class="line">    <span class="attr">actions</span>:&#123;&#125;,</span><br><span class="line">    <span class="attr">modules</span>:&#123;</span><br><span class="line">        homeModule</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"> </span><br><span class="line"><span class="comment">/* 从模块中获取 State 数据 */</span></span><br><span class="line">$store.<span class="property">state</span>.<span class="property">home</span>.<span class="property">name</span> <span class="comment">//123</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> *	默认情况 getters、mutations、action 不需要加模块名，会被合并到store中，与外面store的用法一致   </span></span><br><span class="line"><span class="comment"> *  	容易名字冲突</span></span><br><span class="line"><span class="comment"> *  开启命名空间</span></span><br><span class="line"><span class="comment"> *	     namespaced:true  </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line">$store.<span class="property">getters</span>[<span class="string">&quot;home/homeGetters&quot;</span>]</span><br><span class="line">store.<span class="title function_">dispatch</span>(<span class="string">&quot;home/homeAction&quot;</span>,<span class="literal">null</span>,&#123;<span class="attr">root</span>:<span class="literal">true</span>&#125;) <span class="comment">// &#123;root:true&#125; 那么里面就能修改根store的数据</span></span><br><span class="line">store.<span class="title function_">commit</span>(<span class="string">&quot;home/homeMutation&quot;</span>)</span><br></pre></td></tr></table></figure>



<blockquote>
<p>  store 仓库的定义</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// npm install vuex; </span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *  src/store/index.js 创建 store</span></span><br><span class="line"><span class="comment"> *  state 所有状态都是响应式的</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore &#125; <span class="keyword">from</span> <span class="string">&quot;vuex&quot;</span>;</span><br><span class="line"><span class="keyword">const</span> store = <span class="title function_">createStore</span>(&#123;</span><br><span class="line">    <span class="attr">state</span>:<span class="function">() =&gt;</span> (&#123;</span><br><span class="line">        <span class="attr">counter</span>:<span class="number">0</span>,</span><br><span class="line">        <span class="attr">name</span>:<span class="string">&quot;lzo&quot;</span>,</span><br><span class="line">        <span class="attr">level</span>:<span class="number">10</span></span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="attr">getters</span>:&#123;</span><br><span class="line">       <span class="title function_">doubleCounter</span>(<span class="params">state,getters</span>)&#123; </span><br><span class="line">           <span class="keyword">return</span> state.<span class="property">counter</span>*<span class="number">2</span> + getters.<span class="property">message</span></span><br><span class="line">       &#125;, </span><br><span class="line">       <span class="title function_">message</span>(<span class="params">state</span>)&#123;</span><br><span class="line">           <span class="keyword">return</span> state.<span class="property">level</span> + <span class="number">3</span>;</span><br><span class="line">       &#125;,</span><br><span class="line">       <span class="title function_">func</span>(<span class="params">state</span>)&#123;</span><br><span class="line">           <span class="keyword">return</span><span class="function">(<span class="params">id</span>)=&gt;</span>&#123;</span><br><span class="line">               <span class="keyword">return</span> id + state.<span class="property">level</span>;</span><br><span class="line">           &#125;</span><br><span class="line">           <span class="comment">// $store.getters.func(5)  --&gt; 15</span></span><br><span class="line">       &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">mutations</span>: &#123;</span><br><span class="line">        <span class="comment">/* 先导入常量 CHANGE_NAME，commit  的时候同样导入 */</span></span><br><span class="line">        [<span class="variable constant_">CHANGE_NAME</span>](state,payload)&#123;</span><br><span class="line">            state.<span class="property">counter</span>++;</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="title function_">increment</span>(<span class="params">state,payload</span>)&#123;</span><br><span class="line">            state.<span class="property">counter</span>++;</span><br><span class="line">            state.<span class="property">name</span> = payload||<span class="string">&#x27;lzo&#x27;</span>;</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="title function_">fromAction</span>(<span class="params">state,payload</span>)&#123;</span><br><span class="line">            state.<span class="property">level</span> = payload;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">actions</span>:&#123;</span><br><span class="line">        <span class="title function_">changeLevelAction</span>(<span class="params">context,payload</span>)&#123;</span><br><span class="line">            <span class="comment">/* context 上下文  和  store 有相同的属性和方法 */</span></span><br><span class="line">            <span class="comment">/* context.commit(&quot;increment&quot;) 提交 mutation */</span></span><br><span class="line">            <span class="comment">/* context.state 和 context.getters 来获取State 或 Getters 数据*/</span></span><br><span class="line">            context.<span class="title function_">commit</span>(<span class="string">&quot;fromAction&quot;</span>,payload);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> store;</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.js</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&quot;./store&quot;</span>;</span><br><span class="line">app.<span class="title function_">use</span>(store)</span><br></pre></td></tr></table></figure>



<blockquote>
<p>  核心概念 State、Getters、Mutations、Actions、Modules； </p>
</blockquote>
<p><strong>State</strong> 状态对象集合</p>
<p><strong>Getters</strong> 将state中的数据需要经过加工之后再使用，<strong>类似计算属性</strong></p>
<p><strong>Mutations</strong> 更改vuex状态的<strong>唯一标准方法</strong>是 <code>commit</code> 提交 <code>mutations</code> </p>
<p>​			( Mutations <strong>同步操</strong>作，<strong>可以</strong>但是<strong>不要做异步操作</strong>，如果要，可以经过<strong>Actions</strong>异步操作，再<strong>从 Actions  提交 Mutations</strong>)</p>
<p><strong>Action</strong>  类似 mutation，不同在于Action可以包含异步操作，但是不能直接修改state，而是要 commit 到 mutation 去改变 </p>
<p>​			( 打算将公共数据存在store，就可以在Action获取数据，其他地方直接从store获取 )</p>
<p><strong>Modules</strong>  将 store 数据 拆分管理</p>
<h2 id="Pinia-Vuex-5"><a href="#Pinia-Vuex-5" class="headerlink" title="Pinia(Vuex 5)"></a>Pinia(Vuex 5)</h2><p>推荐在 <code>vue3 setup</code> 中使用</p>
<blockquote>
<p>  与 vuex 的区别</p>
</blockquote>
<ul>
<li><code>mutations</code> 不存在了，action就能直接修改 state</li>
<li>更友好的<code>TypeScrip</code>支持，Vuex对TS很不友好</li>
<li>没有了 <code>modules</code> 的嵌套结构<ul>
<li>可以灵活使用多个<code>store</code>，通过<strong>扁平化</strong>的方式<strong>交互使用</strong></li>
<li>没有了命名空间的概念</li>
</ul>
</li>
</ul>
<h3 id="安装配置"><a href="#安装配置" class="headerlink" title="安装配置"></a>安装配置</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 1、npm install pinia  安装*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 2、/store/index.js 引入 配置 关联vue */</span></span><br><span class="line"><span class="keyword">import</span> &#123; createPinia &#125; <span class="keyword">from</span> <span class="string">&#x27;pinia&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> pinia = <span class="title function_">createPinia</span>();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> pinia;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 3、app.use(pinia) */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 4、可以关闭 /store/index 了，新增数据，建立对应的文件，如同级创建 home.js */</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  数据仓库基本定义与使用 </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* home.js */</span></span><br><span class="line"><span class="comment">/* 定义store */</span></span><br><span class="line"><span class="keyword">import</span> &#123;  defineStore &#125; <span class="keyword">from</span> <span class="string">&#x27;pinia&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 定义 store 唯一 名为 home，并返回一个hook函数 */</span></span><br><span class="line"><span class="keyword">const</span> useHome = <span class="title function_">defineStore</span>(<span class="string">&#x27;home&#x27;</span>,&#123;  </span><br><span class="line">    <span class="attr">state</span>:<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="attr">name</span>:<span class="string">&#x27;lzoxun&#x27;</span>,</span><br><span class="line">        <span class="attr">count</span>:<span class="number">2</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">getters</span>:&#123;</span><br><span class="line">        <span class="title function_">doubleCount</span>(<span class="params">state</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> state.<span class="property">count</span> * <span class="number">2</span>; </span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="title function_">doubleCountAdd</span>(<span class="params">state</span>)&#123;</span><br><span class="line">            <span class="comment">// this 是 store 实例</span></span><br><span class="line">            <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">doubleCount</span> + <span class="number">1</span>;</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="title function_">dynamicParams</span>(<span class="params">state</span>)&#123;</span><br><span class="line">    		<span class="keyword">return</span> <span class="function">(<span class="params">id</span>)=&gt;</span>&#123;</span><br><span class="line">                <span class="keyword">return</span> state.<span class="property">count</span> + id;</span><br><span class="line">            &#125;</span><br><span class="line">		&#125;,</span><br><span class="line">        <span class="title function_">otherStore</span>(<span class="params">state</span>)&#123;</span><br><span class="line">            <span class="keyword">const</span> userStore = <span class="title function_">useUser</span>(); <span class="comment">// 需要先 导入</span></span><br><span class="line">            <span class="keyword">return</span> userStore.<span class="property">name</span> + state.<span class="property">name</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">actions</span>:&#123;</span><br><span class="line">        <span class="title function_">incrment</span>(<span class="params">payload</span>)&#123; <span class="comment">// 没有state，直接是参数</span></span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">count</span>++;</span><br><span class="line">        &#125;,</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> useStoretag;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 页面 setup 中 */</span></span><br><span class="line"><span class="keyword">import</span> useHome <span class="keyword">from</span> <span class="string">&quot;@/store/home&quot;</span></span><br><span class="line"><span class="keyword">import</span> &#123; storeToRefs &#125; <span class="keyword">from</span> <span class="string">&#x27;pinia&#x27;</span>；</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> homeStore = <span class="title function_">useHome</span>();</span><br><span class="line"><span class="keyword">const</span> &#123; name &#125; = <span class="title function_">storeToRefs</span>(homeStore); <span class="comment">// 类似 toRefs 解构之后还能响应式</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 使用或修改 store 数据 */</span> </span><br><span class="line">homeStore.<span class="property">name</span>                       </span><br><span class="line">homeStore.<span class="property">name</span> = <span class="string">&#x27;xun&#x27;</span> </span><br><span class="line"></span><br><span class="line"><span class="comment">/* 修改多个状态 */</span></span><br><span class="line">homeStore.$patch(&#123;</span><br><span class="line">    <span class="attr">name</span>:<span class="string">&quot;789&quot;</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 重置 store 数据到最初始的状态 */</span></span><br><span class="line">homeStore.$reset() </span><br><span class="line"></span><br><span class="line"><span class="comment">/* 替换整个state */</span></span><br><span class="line">homeStore.<span class="property">$state</span> = &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* getters 方法 */</span></span><br><span class="line">homeStore.<span class="title function_">doubleCount</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">/* actions 方法, 如果返回的是promise，可以通过then监听异步结果 */</span></span><br><span class="line">homeStore.<span class="title function_">incrment</span>(<span class="number">10</span>); </span><br></pre></td></tr></table></figure>

<h3 id="三个核心概念"><a href="#三个核心概念" class="headerlink" title="三个核心概念"></a>三个核心概念</h3><p><code>state</code>、<code>getters</code>、<code>actions</code> 等同于组件的 <code>data</code>、<code>computed</code>、<code>methods</code>，定义成功后可以直接使用</p>
<h2 id="脚手架"><a href="#脚手架" class="headerlink" title="脚手架"></a>脚手架</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 全局安装 vue</span></span><br><span class="line">npm install @vue/cli -g</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建项目</span></span><br><span class="line">vue create &lt;project-name&gt;</span><br><span class="line">    </span><br></pre></td></tr></table></figure>

<blockquote>
<p>  browserslist  设置babel转换代码的标准</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&gt; 1%&quot;</span>, <span class="comment">// 适配市场占有率大于1%的浏览器</span></span><br><span class="line"><span class="string">&quot;last 2 versions&quot;</span>,</span><br><span class="line"><span class="string">&quot;not dead&quot;</span>,</span><br><span class="line"><span class="string">&quot;not ie 11&quot;</span>, <span class="comment">// 不需要支持ie11  </span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  jsconfig.json  让vscode提供友好的代码提示</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;compilerOptions&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;target&quot;</span>: <span class="string">&quot;es5&quot;</span>,</span><br><span class="line">    <span class="string">&quot;module&quot;</span>: <span class="string">&quot;esnext&quot;</span>,</span><br><span class="line">    <span class="string">&quot;baseUrl&quot;</span>: <span class="string">&quot;./&quot;</span>, <span class="comment">// paths中src相对路径</span></span><br><span class="line">    <span class="string">&quot;moduleResolution&quot;</span>: <span class="string">&quot;node&quot;</span>,</span><br><span class="line">    <span class="string">&quot;paths&quot;</span>: &#123;</span><br><span class="line">      <span class="string">&quot;@/*&quot;</span>: [<span class="string">&quot;src/*&quot;</span>],  <span class="comment">// 当用户输入@，vscode就会提示去src/下找东西</span></span><br><span class="line">      <span class="string">&quot;utils/*&quot;</span>:[src/utils<span class="comment">/*] // 当用户输入utils，vscode就会提示去src/utils下找东西</span></span><br><span class="line"><span class="comment">    &#125;,</span></span><br><span class="line"><span class="comment">    &quot;lib&quot;: [&quot;esnext&quot;, &quot;dom&quot;, &quot;dom.iterable&quot;, &quot;scripthost&quot;]</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>  引入 vue 构建版本问题</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 编译过程：模板html --createVnode()--&gt; VNode -&gt; 虚拟DOM -&gt; 真实DOM</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 预先编译</span></span><br><span class="line"><span class="comment"> * 默认 import &#123; createApp &#125; from &quot;vue&quot;</span></span><br><span class="line"><span class="comment"> *     不支持template选项，需要通过.vue文件引入</span></span><br><span class="line"><span class="comment"> *     以前的runtime版本 </span></span><br><span class="line"><span class="comment"> *     编译功能的实现代码，不是存在vue源码中</span></span><br><span class="line"><span class="comment"> *            webpack处理vue-loader处理.vue 时预先编译就实现了 html --createVnode()的过程</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *  运行时编译</span></span><br><span class="line"><span class="comment"> *  import &#123; createApp &#125; from &quot;vue/dist/vue.esm-bundler&quot;</span></span><br><span class="line"><span class="comment"> *     支持template选项，模板html在属性中，vue-loader无法处理，所有编译代码集成到vue.esm-bundler源码中</span></span><br><span class="line"><span class="comment"> *     以前的runtime+compile版本  runtime+编译 </span></span><br><span class="line"><span class="comment"> *     编译功能的实现代码，存放在vue.esm-bundler，vue源码中</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<h4 id="打包"><a href="#打包" class="headerlink" title="打包"></a>打包</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">app.xxxxx.js            默认存放所有自己编写的代码</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">chunk-vendors.xxxx.js   保持所有的第三方库</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">浏览器渲染需要把 app,vendors 下载才能渲染（如果把app拆分，把单前页面的文件下载就可以渲染）</span>  </span><br><span class="line"></span><br><span class="line">import(&quot;./components/cpn1.vue&quot;).then(res=&gt;&#123;&#125;) # 可以对导入的文件进行分包处理 </span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">vue 异步引入组件</span></span><br><span class="line">import &#123; defineAsyncComponent &#125; from &quot;vue&quot;;</span><br><span class="line">const Cpn1 = defineAsyncComponent(()=&gt; import(&quot;./components/cpn1.vue&quot;))</span><br></pre></td></tr></table></figure>

<h2 id="Axios"><a href="#Axios" class="headerlink" title="Axios"></a>Axios</h2><blockquote>
<p>  浏览器原生网络请求 <strong>XMLHttpRequire</strong>、<strong>fetch</strong></p>
</blockquote>
<h4 id="认识-Axios"><a href="#认识-Axios" class="headerlink" title="认识 Axios"></a>认识 Axios</h4><p>特点</p>
<ul>
<li>在浏览器发送 <strong>XMLHttpRequire</strong> ，Node环境自动发送 <strong>http</strong> 请求</li>
<li>支持 Promise API</li>
<li>拦截请求和响应</li>
</ul>
<h4 id="axios-发送请求"><a href="#axios-发送请求" class="headerlink" title="axios 发送请求"></a>axios 发送请求</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 基本用法 */</span></span><br><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&quot;axios&quot;</span>;</span><br><span class="line">axios.<span class="property">defaults</span>.<span class="property">baseURL</span> = process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>; <span class="comment">// 提取出来</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 1、 get 带参数 */</span></span><br><span class="line">axios.<span class="title function_">get</span>(<span class="string">`/juhe/video/update`</span>, &#123; <span class="attr">params</span>: &#123; <span class="attr">id</span>: <span class="number">1</span> &#125; &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 2、 post 带参数 */</span></span><br><span class="line">axios.<span class="title function_">post</span>(<span class="string">`/users/login`</span>, &#123; <span class="string">&quot;nam e&quot;</span>: <span class="string">&quot;zhong&quot;</span>, <span class="string">&quot;passwd&quot;</span>: <span class="string">&quot;456&quot;</span> &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 3、 axios request */</span></span><br><span class="line">axios.<span class="title function_">request</span>(&#123;</span><br><span class="line">    <span class="attr">url</span>: <span class="string">`/users/login`</span>,</span><br><span class="line">    <span class="attr">data</span>: &#123; <span class="string">&quot;name&quot;</span>: <span class="string">&quot;zhong&quot;</span>, <span class="string">&quot;passwd&quot;</span>: <span class="string">&quot;456&quot;</span> &#125;,</span><br><span class="line">    <span class="attr">method</span>: <span class="string">&#x27;post&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line">).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 4、 axios all =&gt; Promist.all  全部成功再走then*/</span></span><br><span class="line">axios.<span class="title function_">all</span>([</span><br><span class="line">    axios.<span class="title function_">get</span>(<span class="string">`/juhe/video/update`</span>, &#123; <span class="attr">params</span>: &#123; <span class="attr">id</span>: <span class="number">1</span> &#125; &#125;),</span><br><span class="line">    axios.<span class="title function_">post</span>(<span class="string">`/users/login`</span>, &#123; <span class="string">&quot;nam e&quot;</span>: <span class="string">&quot;zhong&quot;</span>, <span class="string">&quot;passwd&quot;</span>: <span class="string">&quot;456&quot;</span> &#125;)</span><br><span class="line">]).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h4 id="axios创建实例"><a href="#axios创建实例" class="headerlink" title="axios创建实例"></a>axios创建实例</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&quot;axios&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> baseURL = <span class="string">&quot;/&quot;</span>; <span class="comment">/* 为了兼容vue跨域代理，设置地址的话代理无效 */</span></span><br><span class="line"><span class="keyword">if</span> (process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">&#x27;production&#x27;</span>) &#123;</span><br><span class="line">    baseURL = process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* service 实例的公共配置，如果要从多个服务器调接口，可以配置多个实例  */</span></span><br><span class="line"><span class="keyword">const</span> service = axios.<span class="title function_">create</span>(&#123;</span><br><span class="line">    baseURL,</span><br><span class="line">    <span class="attr">timeout</span>: <span class="number">10000</span>,</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">service.<span class="title function_">get</span>(<span class="string">`/juhe/video/update`</span>, &#123; <span class="attr">params</span>: &#123; <span class="attr">id</span>: <span class="number">1</span> &#125; &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h4 id="axios-拦截器"><a href="#axios-拦截器" class="headerlink" title="axios 拦截器"></a>axios 拦截器</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&quot;axios&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> baseURL = <span class="string">&quot;/&quot;</span>;</span><br><span class="line"><span class="keyword">if</span> (process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">&#x27;production&#x27;</span>) &#123;</span><br><span class="line">    baseURL = process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> service = axios.<span class="title function_">create</span>(&#123;</span><br><span class="line">    baseURL,</span><br><span class="line">    <span class="attr">timeout</span>: <span class="number">10000</span>,</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 请求拦截 请求之前，拦截提交的配置，处理完再继续发送 */</span></span><br><span class="line">service.<span class="property">interceptors</span>.<span class="property">request</span>.<span class="title function_">use</span>(<span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;请求成功拦截回调&quot;</span>)</span><br><span class="line">    config.<span class="property">headers</span>[<span class="string">&#x27;token&#x27;</span>] = <span class="string">&#x27;xxxx&#x27;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> config;</span><br><span class="line">&#125;, <span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;请求失败拦截回调&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 响应拦截 响应给用户之前，拦截响应的数据，处理完成在继续响应*/</span></span><br><span class="line">service.<span class="property">interceptors</span>.<span class="property">response</span>.<span class="title function_">use</span>(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;响应成功回调&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> res.<span class="property">data</span>;</span><br><span class="line">&#125;, <span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;响应失败回调&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">service.<span class="title function_">get</span>(<span class="string">`/juhe/video/update`</span>, &#123; <span class="attr">params</span>: &#123; <span class="attr">id</span>: <span class="number">1</span> &#125; &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h4 id="axios-请求封装"><a href="#axios-请求封装" class="headerlink" title="axios 请求封装"></a>axios 请求封装</h4> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&quot;axios&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">LzoRequest</span> &#123;</span><br><span class="line">    <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">let</span> baseURL = <span class="string">&quot;/&quot;</span>;</span><br><span class="line">        <span class="keyword">if</span> (process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">&#x27;production&#x27;</span>) &#123;</span><br><span class="line">            baseURL = process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">service</span> = axios.<span class="title function_">create</span>(&#123;</span><br><span class="line">            <span class="attr">baseURL</span>: process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>,</span><br><span class="line">            <span class="attr">timeout</span>: <span class="number">10000</span>,</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* 请求拦截 请求之前，拦截提交的配置，处理完再继续发送 */</span></span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">service</span>.<span class="property">interceptors</span>.<span class="property">request</span>.<span class="title function_">use</span>(<span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;请求成功拦截回调&quot;</span>)</span><br><span class="line">            config.<span class="property">headers</span>[<span class="string">&#x27;token&#x27;</span>] = <span class="string">&#x27;xxxx&#x27;</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> config;</span><br><span class="line">        &#125;, <span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;请求失败拦截回调&quot;</span>)</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* 响应拦截 响应给用户之前，拦截响应的数据，处理完成在继续响应*/</span></span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">service</span>.<span class="property">interceptors</span>.<span class="property">response</span>.<span class="title function_">use</span>(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;响应成功回调&quot;</span>)</span><br><span class="line">            <span class="keyword">return</span> res.<span class="property">data</span>;</span><br><span class="line">        &#125;, <span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;响应失败回调&quot;</span>)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="title function_">request</span>(<span class="params">config</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">service</span>.<span class="title function_">request</span>(config).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">                <span class="title function_">resolve</span>(res)</span><br><span class="line">            &#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span> =&gt;</span> &#123;</span><br><span class="line">                <span class="title function_">reject</span>(err)</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="title function_">get</span>(<span class="params">config</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">request</span>(&#123; ...config, <span class="attr">method</span>: <span class="string">&quot;get&quot;</span> &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="title function_">post</span>(<span class="params">config</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">request</span>(&#123; ...config, <span class="attr">method</span>: <span class="string">&quot;post&quot;</span> &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> lzor = <span class="keyword">new</span> <span class="title class_">LzoRequest</span>();</span><br><span class="line"></span><br><span class="line">lzor.<span class="title function_">get</span>(&#123; <span class="attr">url</span>: <span class="string">`/juhe/video/update`</span>, <span class="attr">params</span>: &#123; <span class="attr">id</span>: <span class="number">1</span> &#125; &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(res,<span class="number">37</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> lzor;</span><br><span class="line"></span><br><span class="line"><span class="comment">// import Lzo from &quot;./utils/axios&quot;</span></span><br><span class="line"><span class="comment">// Lzo.get(&#123; url: `/juhe/video/update`, params: &#123; id: 1 &#125; &#125;).then(res =&gt; &#123;</span></span><br><span class="line"><span class="comment">//     console.log(res,38)</span></span><br><span class="line"><span class="comment">// &#125;)</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><h4 id="安装-谷歌插件-dev-tools"><a href="#安装-谷歌插件-dev-tools" class="headerlink" title="安装 谷歌插件 dev-tools"></a>安装 谷歌插件 dev-tools</h4><blockquote>
<p>  如果商店进不了 ，<a target="_blank" rel="noopener" href="https://github.com/vuejs/devtools">dev-tools</a> clone 源码 ，npm run build 打包</p>
</blockquote>
<blockquote>
<p>  google 浏览器中 加载已解压的扩展程序</p>
</blockquote>
<h4 id="scoped-实现原理"><a href="#scoped-实现原理" class="headerlink" title="scoped 实现原理"></a>scoped 实现原理</h4><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">scoped</span></span><br><span class="line"><span class="comment">	vue 中 设置scoped , 就会在该组件最顶层元素添加 自定义属性 data-v-xxxxxxx</span></span><br><span class="line"><span class="comment">	所有子元素也会添加上同样的 data-v-xxxxxxx</span></span><br><span class="line"><span class="comment">	嵌套的组件,如果是单根元素，也会添加同样的 data-v-xxxxxxx，如果有多个根节点增不会有</span></span><br><span class="line"><span class="comment">	所以 scoped 的样式某个组件中，可以设置存在 data-v-xxxxxxx 节点的样式(包括本组件所有元素与嵌套组件根元素)</span></span><br><span class="line"><span class="comment">	如果 向设置嵌套组件里面的其他元素 需要用 :deep(&#x27;选择器&#x27;) 才能深度设置</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	如果是挂载到 #app 外面的元素，需要 :global(&#x27;选择器&#x27;) 才能设置</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	如果页面中嵌套logo组件，并且logo组件唯一根元素的class是logo</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">   <span class="selector-class">.logo</span> &#123; <span class="comment">/* 有效 */</span></span><br><span class="line">       :<span class="built_in">deep</span>(.font) &#123;</span><br><span class="line">           <span class="attribute">background-color</span>: <span class="number">#f0f</span>;</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br><span class="line">   :<span class="built_in">deep</span>(.logo) &#123; <span class="comment">/* 有效 */</span></span><br><span class="line">       <span class="selector-class">.font</span> &#123;</span><br><span class="line">           <span class="attribute">background-color</span>: <span class="number">#f0f</span>;</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="selector-class">.logo</span> &#123; <span class="comment">/* 无效 */</span></span><br><span class="line">       <span class="selector-class">.font</span> &#123;</span><br><span class="line">           <span class="attribute">background-color</span>: <span class="number">#f0f</span>;</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="http://example.com">lzoxun</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://example.com/2023/07/22/web/vue/vue-vue3-coderw/">http://example.com/2023/07/22/web/vue/vue-vue3-coderw/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://example.com" target="_blank">学习笔记</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"></div><div class="post_share"><div class="social-share" data-image="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2023/07/22/web/vue/vue-vuecli/" title=""><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info"></div></div></a></div><div class="next-post pull-right"><a href="/2023/07/22/web/vue/vue-router/" title="vue-router"><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">vue-router</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "" data-lazy-src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">lzoxun</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">108</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">1</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/liaozhongxun"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/liaozhongxun" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:869664233@gmail.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">这是我的文档</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Options-Api-%E9%80%89%E9%A1%B9API"><span class="toc-number">1.</span> <span class="toc-text">Options Api (选项API)</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%BC%80%E5%90%AF-vue"><span class="toc-number">1.0.1.</span> <span class="toc-text">开启 vue</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E8%AF%AD%E6%B3%95"><span class="toc-number">1.0.2.</span> <span class="toc-text">模板语法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#MVC-%E4%B8%8E-MVVM"><span class="toc-number">1.0.3.</span> <span class="toc-text">MVC 与 MVVM</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E5%8C%96"><span class="toc-number">1.0.4.</span> <span class="toc-text">组件化</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%8F%92%E6%A7%BD"><span class="toc-number">1.0.5.</span> <span class="toc-text">插槽</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Composition-Api-%EF%BC%88%E7%BB%84%E5%90%88API%EF%BC%89"><span class="toc-number">2.</span> <span class="toc-text">Composition Api （组合API）</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E4%B8%8A%E4%B8%8B%E6%96%87"><span class="toc-number">2.0.1.</span> <span class="toc-text">Setup 上下文</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E5%AE%9E%E7%8E%B0-data-%E6%95%B0%E6%8D%AE"><span class="toc-number">2.0.2.</span> <span class="toc-text">Setup 实现 data  数据</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E5%AE%9E%E7%8E%B0-%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7"><span class="toc-number">2.0.3.</span> <span class="toc-text">Setup 实现 计算属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E5%AE%9E%E7%8E%B0-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-number">2.0.4.</span> <span class="toc-text">Setup 实现 生命周期</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E5%AE%9E%E7%8E%B0-Provide-Inject"><span class="toc-number">2.0.5.</span> <span class="toc-text">Setup 实现 Provide&#x2F;Inject</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-%E5%AE%9E%E7%8E%B0-watch-watchEffect"><span class="toc-number">2.0.6.</span> <span class="toc-text">Setup 实现 watch&#x2F;watchEffect</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Setup-script%E8%AF%AD%E6%B3%95%E7%B3%96"><span class="toc-number">2.0.7.</span> <span class="toc-text">Setup script语法糖</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1"><span class="toc-number">3.</span> <span class="toc-text">路由</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#vue-router"><span class="toc-number">3.1.</span> <span class="toc-text">vue-router</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8A%A8%E6%80%81%E9%85%8D%E7%BD%AE%E8%B7%AF%E7%94%B1"><span class="toc-number">3.1.1.</span> <span class="toc-text">动态配置路由</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Vuex"><span class="toc-number">4.</span> <span class="toc-text">Vuex</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Pinia-Vuex-5"><span class="toc-number">5.</span> <span class="toc-text">Pinia(Vuex 5)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE"><span class="toc-number">5.1.</span> <span class="toc-text">安装配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%89%E4%B8%AA%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"><span class="toc-number">5.2.</span> <span class="toc-text">三个核心概念</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%84%9A%E6%89%8B%E6%9E%B6"><span class="toc-number">6.</span> <span class="toc-text">脚手架</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%89%93%E5%8C%85"><span class="toc-number">6.0.1.</span> <span class="toc-text">打包</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Axios"><span class="toc-number">7.</span> <span class="toc-text">Axios</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AE%A4%E8%AF%86-Axios"><span class="toc-number">7.0.1.</span> <span class="toc-text">认识 Axios</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#axios-%E5%8F%91%E9%80%81%E8%AF%B7%E6%B1%82"><span class="toc-number">7.0.2.</span> <span class="toc-text">axios 发送请求</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#axios%E5%88%9B%E5%BB%BA%E5%AE%9E%E4%BE%8B"><span class="toc-number">7.0.3.</span> <span class="toc-text">axios创建实例</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#axios-%E6%8B%A6%E6%88%AA%E5%99%A8"><span class="toc-number">7.0.4.</span> <span class="toc-text">axios 拦截器</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#axios-%E8%AF%B7%E6%B1%82%E5%B0%81%E8%A3%85"><span class="toc-number">7.0.5.</span> <span class="toc-text">axios 请求封装</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B6%E4%BB%96"><span class="toc-number">8.</span> <span class="toc-text">其他</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AE%89%E8%A3%85-%E8%B0%B7%E6%AD%8C%E6%8F%92%E4%BB%B6-dev-tools"><span class="toc-number">8.0.1.</span> <span class="toc-text">安装 谷歌插件 dev-tools</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#scoped-%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86"><span class="toc-number">8.0.2.</span> <span class="toc-text">scoped 实现原理</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2023/07/22/window/win-11/" title="win 11 set">win 11 set</a><time datetime="2023-07-22T07:14:09.700Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2023/07/22/window/win-gitbash/" title="git bash">git bash</a><time datetime="2023-07-22T07:14:09.700Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2023/07/22/window/win-wsl/" title="wsl">wsl</a><time datetime="2023-07-22T07:14:09.700Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2023/07/22/window/win-main/" title="window">window</a><time datetime="2023-07-22T07:14:09.700Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2023/07/22/web/%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98/" title="兼容问题">兼容问题</a><time datetime="2023-07-22T07:14:09.699Z" title="发表于 2023-07-22 15:14:09">2023-07-22</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By lzoxun</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script>function panguFn () {
  if (typeof pangu === 'object') pangu.autoSpacingPage()
  else {
    getScript('https://cdn.jsdelivr.net/npm/pangu/dist/browser/pangu.min.js')
      .then(() => {
        pangu.autoSpacingPage()
      })
  }
}

function panguInit () {
  if (false){
    GLOBAL_CONFIG_SITE.isPost && panguFn()
  } else {
    panguFn()
  }
}

document.addEventListener('DOMContentLoaded', panguInit)</script><div class="js-pjax"></div><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="99" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-nest.min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div class="no-result" id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></div><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"log":false,"model":{"jsonPath":"/live2dw/assets/haruto.model.json"},"display":{"position":"right","width":100,"height":200,"right":300},"mobile":{"show":true}});</script></body></html>